
#ifndef Dictionary_t_h
#define Dictionary_t_h

// Std includes.
#include <stdio.h>   /* gets */
#include <stdlib.h>  /* atoi, malloc */
#include <string.h>  /* strcpy */

#include "map/uthash.h"

// CSharp includes.
#include <Typedef.h>
#include <CSharpPropertyMethods.h>
#include <Defines.h>

// Riccsson includes.
#include <System/Collections/Generic/List.h>
#include <System/Collections/Generic/IDictionary.h>
#include <System/Collections/Generic/ICollection.h>
#include <System/Collections/Generic/IEnumerable.h>
#include <System/Collections/Generic/KeyNotFoundException.h>
#include <System/IDisposable.h>
#include <System/ArgumentException.h>
#include <System/ArgumentNullException.h>
#include <System/IndexOutOfRangeException.h>
#include <System/InvalidOperationException.h>
#include <System/ArgumentOutOfRangeException.h>

namespace Riccsson
{
	namespace System
	{
		namespace Collections
		{
			namespace Generic
			{

				template<typename TKey, typename TValue>
				class Dictionary
					: public Riccsson::System::Object
					, public Riccsson::System::Collections::Generic::IDictionary<TKey, TValue>
				{
					template<typename Key> struct my_struct
					{
						int ikey;
						Key id;
						TValue value;

						UT_hash_handle hh; // Makes this structure hashable.
					};

					struct my_struct<TKey>* _internalMap; // important! initialize to NULL.
					List<int> _listOfKeys; // TODO: This is only to make begin() end() to work. Maybe fix this on another better way?

				public:

					typedef void* iterator;
					typedef const void* const_iterator;

					using IEnumerable< KeyValuePair<TKey, TValue> >::begin;
					using IEnumerable< KeyValuePair<TKey, TValue> >::end;

					// Summary:
					//     Represents the collection of keys or values in a System.Collections.Generic.Dictionary<TKey,TValue>.
					//     This class cannot be inherited.
					public: template<typename T> class Collection sealed
						: public ICollection<T>
					{
					public:
						using IEnumerable<T>::begin;
						using IEnumerable<T>::end;

						// Summary:
						//     Enumerates the elements of a System.Collections.Generic.Dictionary<TKey,TValue>.KeyCollection.
						public: struct Enumerator : IEnumerator<T>//, IDisposable, IEnumerator
						{
						private:
							// Private variables.
							List<T>* m_internalVector;
							int m_currentIndex;
							int m_maxIndex;

							//------------------------------------------------------------------------------
							// Constructor.
							public: Enumerator(List<T>* internalVector)
								: IEnumerator<T>()
								, m_internalVector(internalVector)
								, m_currentIndex(0)
								, m_maxIndex(internalVector->Count)
							{
							}

							// Summary:
							//     Gets the element at the current position of the enumerator.
							//
							// Returns:
							//     The element in the System.Collections.Generic.List<T> at the current position
							//     of the enumerator.
							PROP3_GET(T, Current)
							{
								return m_internalVector->at(m_currentIndex);
							}

							public: void setMax(int size)
							{
								m_maxIndex = size;
							}

							public: void setIndex(int index)
							{
								if(index > m_maxIndex) throw ArgumentOutOfRangeException("Cannot assign an enumerator index higher than Max.");
								m_currentIndex = index;
							}

							// Summary:
							//     Releases all resources used by the System.Collections.Generic.List<T>.Enumerator.
							//[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
							public: void Dispose()
							{
								throw;
							}

							//
							// Summary:
							//     Advances the enumerator to the next element of the System.Collections.Generic.List<T>.
							//
							// Returns:
							//     true if the enumerator was successfully advanced to the next element; false
							//     if the enumerator has passed the end of the collection.
							//
							// Exceptions:
							//   System.InvalidOperationException:
							//     The collection was modified after the enumerator was created.
							public: bool MoveNext()
							{
								// Check if list has been modified after the enumerator has been created.
								if(m_maxIndex != m_internalVector->Count)
								{
									throw InvalidOperationException("The collection was modified after the enumerator was created.");
								}

								// Move to next index.
								++m_currentIndex;

								// Return true if current index is under the max index.
								return m_currentIndex < m_maxIndex;
							}

							//
							// Summary:
							//     Sets the enumerator to its initial position, which is before the first element
							//     in the collection.
							//
							// Exceptions:
							//   System.InvalidOperationException:
							//     The collection was modified after the enumerator was created.
							public: void Reset()
							{
								// Check if list has been modified after the enumerator has been created.
								if(m_maxIndex != m_internalVector->Count)
								{
									throw InvalidOperationException("The collection was modified after the enumerator was created.");
								}

								m_currentIndex = 0;
							}
						};

					private:
						Dictionary<TKey, TValue>* _dictionary;
						List<T> _internalVector;
						Enumerator* _enum;

						// Summary:
						//     Initializes a new instance of the System.Collections.Generic.Dictionary<TKey,TValue>.KeyCollection
						//     class that reflects the keys in the specified System.Collections.Generic.Dictionary<TKey,TValue>.
						//
						// Parameters:
						//   dictionary:
						//     The System.Collections.Generic.Dictionary<TKey,TValue> whose keys are reflected
						//     in the new System.Collections.Generic.Dictionary<TKey,TValue>.KeyCollection.
						//
						// Exceptions:
						//   System.ArgumentNullException:
						//     dictionary is null.
						public: Collection(Dictionary<TKey, TValue>* dictionary)
							: _enum(new Enumerator(&_internalVector))
						{
							_dictionary = dictionary;
						}

						private: void regenerate()
						{
							throw;
							//foreach(var item : _dictionary){
							//	 _internalVector.insert(item);
							//}
						}

						// Summary:
						//     Gets the number of elements contained in the System.Collections.Generic.Dictionary<TKey,TValue>.KeyCollection.
						//
						// Returns:
						//     The number of elements contained in the System.Collections.Generic.Dictionary<TKey,TValue>.KeyCollection.Retrieving
						//     the value of this property is an O(1) operation.
						public: override PROP3_GET(int, Count)
						{
							return (int)_dictionary->Count;
						}

						// Summary:
						//     Copies the System.Collections.Generic.Dictionary<TKey,TValue>.KeyCollection
						//     elements to an existing one-dimensional System.Array, starting at the specified
						//     array index.
						//
						// Parameters:
						//   array:
						//     The one-dimensional System.Array that is the destination of the elements
						//     copied from System.Collections.Generic.Dictionary<TKey,TValue>.KeyCollection.
						//     The System.Array must have zero-based indexing.
						//
						//   index:
						//     The zero-based index in array at which copying begins.
						//
						// Exceptions:
						//   System.ArgumentNullException:
						//     array is null.
						//
						//   System.ArgumentOutOfRangeException:
						//     index is less than zero.
						//
						//   System.ArgumentException:
						//     The number of elements in the source System.Collections.Generic.Dictionary<TKey,TValue>.KeyCollection
						//     is greater than the available space from index to the end of the destination
						//     array.
						public: void CopyTo(Array<T>* _array, int index)
						{
							//if(_array == nullptr) throw ArgumentNullException("Array to copy to may not be null.");
							//if( index < 0 ) throw ArgumentOutOfRangeException("Negative index");
							//if(Count > sizeof(_array)/sizeof(T) - index ) throw ArgumentException("The number of elements in the source System.Collections.Generic.Dictionary<TKey,TValue>.KeyCollection is greater than the available space from index to the end of the destination array.");
							//
							//std::copy(_internalVector.begin()+index, _internalVector.end(), _array);
							throw;
						}

						//
						// Summary:
						//     Returns an enumerator that iterates through the System.Collections.Generic.Dictionary<TKey,TValue>.KeyCollection.
						//
						// Returns:
						//     A System.Collections.Generic.Dictionary<TKey,TValue>.KeyCollection.Enumerator
						//     for the System.Collections.Generic.Dictionary<TKey,TValue>.KeyCollection.
						public: IEnumerator<T>* GetEnumerator()
						{
							//_enum->setMax(Count);
							//_enum->setIndex(0);
							//return _enum;
							throw;
						}

						public: override void Add(const T& item)
						{
							_internalVector.Add(item);
						}

						public: override bool Remove(const T& item)
						{
							//std::vector<T>::iterator index = _internalVector.begin();
							//bool found = false;
							//do
							//{
							//	 if((*index) == item)
							//	 {
							//		 found = true;
							//		 break;
							//	 }
							//	 ++index;
							//}while(!found);
							//
							//if(!found) return false;
							//_internalVector.erase(index);
							//return true;
							throw;
						}

#pragma region Unimplemented
						private: override PROP3_GET(bool, IsReadOnly)
						{
							throw;
						}

						private: override void Clear()
						{
							throw;
						}

						private: override bool Contains(const T& item)
						{
							throw;
						}
#pragma endregion
					};


					// Summary:
					//     Enumerates the elements of a System.Collections.Generic.List<T>.
					struct Enumerator
						: public IEnumerator< KeyValuePair<TKey, TValue> >
					{
					private:
						my_struct<TKey>* m_first;
						my_struct<TKey>* m_current;

					public:

						//------------------------------------------------------------------------------
						// Constructor.
						public: Enumerator(my_struct<TKey>* first)
							: IEnumerator< KeyValuePair<TKey, TValue> >()
							, m_first(first)
							, m_current(null)
						{
						}

						// Summary:
						//     Gets the element at the current position of the enumerator.
						//
						// Returns:
						//     The element in the System.Collections.Generic.List<T> at the current position
						//     of the enumerator.
						public: PROP3_GET( KeyValuePair<TKey COMMA TValue> , Current)
						{
							if(m_current == null)
							{
								throw System::InvalidOperationException("");
							}

							return KeyValuePair<TKey, TValue>(m_current->id, m_current->value);
						}

						// Summary:
						//     Releases all resources used by the System.Collections.Generic.List<T>.Enumerator.
						public: void Dispose()
						{
							throw;
						}

						//
						// Summary:
						//     Advances the enumerator to the next element of the System.Collections.Generic.List<T>.
						//
						// Returns:
						//     true if the enumerator was successfully advanced to the next element; false
						//     if the enumerator has passed the end of the collection.
						//
						// Exceptions:
						//   System.InvalidOperationException:
						//     The collection was modified after the enumerator was created.
						public: bool MoveNext()
						{
							//// Check if list has been modified after the enumerator has been created.
							//if(m_maxIndex != m_internalMap->end())
							//{
							//	throw InvalidOperationException("The collection was modified after the enumerator was created.");
							//}

							if(m_current == null)
							{
								m_current = m_first;
							}
							else
							{
								// Move to next index.
								m_current = static_cast<my_struct<TKey>*>(m_current->hh.next);
							}

							// Return false if current index has reach the end.
							if(m_current == null)
							{
								return false;
							}

							// Return true if current as change.
							return true;
						}

						//
						// Summary:
						//     Sets the enumerator to its initial position, which is before the first element
						//     in the collection.
						//
						// Exceptions:
						//   System.InvalidOperationException:
						//     The collection was modified after the enumerator was created.
						public: void Reset()
						{
							//// Check if list has been modified after the enumerator has been created.
							//if(m_maxIndex != m_internalMap->end()) // && m_interalMap.size() == size)
							//{
							//	throw InvalidOperationException("The collection was modified after the enumerator was created.");
							//}

							m_current = null;
						}
					};


				private:
					GC_PTR<Collection<TKey>> _Keys;
					GC_PTR<Collection<TValue>> _Values;
					
					int getKey(int key)
					{
						return key;
					}
					int getKey(void* key)
					{
						return reinterpret_cast<int>(key);
					}
					int getKey(GC_PTR<object> key)
					{
						return key->GetHashCode();
					}
					int getKey(System::string* key)
					{
						return key->GetHashCode();
					}
					//template<TKey> int getKey(TKey key)
					//{
					//	return reinterpret_cast<int>(key);
					//}

					//
					// Summary:
					//     Gets a collection containing the keys in the System.Collections.Generic.Dictionary<TKey,TValue>.
					//
					// Returns:
					//     A System.Collections.Generic.Dictionary<TKey,TValue>.KeyCollection containing
					//     the keys in the System.Collections.Generic.Dictionary<TKey,TValue>.
					// public Dictionary<TKey, TValue>.KeyCollection Keys { get; }
					//PROP3(Dictionary<TKey COMMA TValue>, ICollection<TKey>*, Keys)
					//KeyCollection* _Keys;
					//Property2<Dictionary<TKey, TValue>, KeyCollection* > Keys;
					//GC_PTR<ICollection<TKey>> _Keys;

					//
					// Summary:
					//     Gets a collection containing the values in the System.Collections.Generic.Dictionary<TKey,TValue>.
					//
					// Returns:
					//     A System.Collections.Generic.Dictionary<TKey,TValue>.ValueCollection containing
					//     the values in the System.Collections.Generic.Dictionary<TKey,TValue>.
					// public Dictionary<TKey, TValue>.ValueCollection Values { get; }
					//GC_PTR<ICollection<TKey>> _Values;

					// Summary:
					//     Initializes a new instance of the System.Collections.Generic.Dictionary<TKey,TValue>
					//     class that is empty, has the default initial capacity, and uses the default
					//     equality comparer for the key type.
					public: Dictionary()
						: _internalMap(null)
					{
						_Keys = new Collection<TKey>(this);
						_Values = new Collection<TValue>(this);
					}
					
					//
					// Summary:
					//     Initializes a new instance of the System.Collections.Generic.Dictionary<TKey,TValue>
					//     class that contains elements copied from the specified System.Collections.Generic.IDictionary<TKey,TValue>
					//     and uses the default equality comparer for the key type.
					//
					// Parameters:
					//   dictionary:
					//     The System.Collections.Generic.IDictionary<TKey,TValue> whose elements are
					//     copied to the new System.Collections.Generic.Dictionary<TKey,TValue>.
					//
					// Exceptions:
					//   System.ArgumentNullException:
					//     dictionary is null.
					//
					//   System.ArgumentException:
					//     dictionary contains one or more duplicate keys.
					public: Dictionary(IDictionary<TKey, TValue>* dictionary)
						: _internalMap(null)
					{
						_Keys = new Collection<TKey>(this);
						_Values = new Collection<TValue>(this);

						foreach (var item : dictionary)
						{
							this->Add(item.Value);
						}
					}

					//
					// Summary:
					//     Initializes a new instance of the System.Collections.Generic.Dictionary<TKey,TValue>
					//     class that is empty, has the default initial capacity, and uses the specified
					//     System.Collections.Generic.IEqualityComparer<T>.
					//
					// Parameters:
					//   comparer:
					//     The System.Collections.Generic.IEqualityComparer<T> implementation to use
					//     when comparing keys, or null to use the default System.Collections.Generic.EqualityComparer<T>
					//     for the type of the key.
					//public Dictionary(IEqualityComparer<TKey> comparer);

					//
					// Summary:
					//     Initializes a new instance of the System.Collections.Generic.Dictionary<TKey,TValue>
					//     class that is empty, has the specified initial capacity, and uses the default
					//     equality comparer for the key type.
					//
					// Parameters:
					//   capacity:
					//     The initial number of elements that the System.Collections.Generic.Dictionary<TKey,TValue>
					//     can contain.
					//
					// Exceptions:
					//   System.ArgumentOutOfRangeException:
					//     capacity is less than 0.
					public: Dictionary(int capacity)
						: _internalMap(null)
					{
						throw;
					}

					//
					// Summary:
					//     Initializes a new instance of the System.Collections.Generic.Dictionary<TKey,TValue>
					//     class that contains elements copied from the specified System.Collections.Generic.IDictionary<TKey,TValue>
					//     and uses the specified System.Collections.Generic.IEqualityComparer<T>.
					//
					// Parameters:
					//   dictionary:
					//     The System.Collections.Generic.IDictionary<TKey,TValue> whose elements are
					//     copied to the new System.Collections.Generic.Dictionary<TKey,TValue>.
					//
					//   comparer:
					//     The System.Collections.Generic.IEqualityComparer<T> implementation to use
					//     when comparing keys, or null to use the default System.Collections.Generic.EqualityComparer<T>
					//     for the type of the key.
					//
					// Exceptions:
					//   System.ArgumentNullException:
					//     dictionary is null.
					//
					//   System.ArgumentException:
					//     dictionary contains one or more duplicate keys.
					//public: Dictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer);

					//
					// Summary:
					//     Initializes a new instance of the System.Collections.Generic.Dictionary<TKey,TValue>
					//     class that is empty, has the specified initial capacity, and uses the specified
					//     System.Collections.Generic.IEqualityComparer<T>.
					//
					// Parameters:
					//   capacity:
					//     The initial number of elements that the System.Collections.Generic.Dictionary<TKey,TValue>
					//     can contain.
					//
					//   comparer:
					//     The System.Collections.Generic.IEqualityComparer<T> implementation to use
					//     when comparing keys, or null to use the default System.Collections.Generic.EqualityComparer<T>
					//     for the type of the key.
					//
					// Exceptions:
					//   System.ArgumentOutOfRangeException:
					//     capacity is less than 0.
					//public: Dictionary(int capacity, IEqualityComparer<TKey> comparer);

					//
					// Summary:
					//     Initializes a new instance of the System.Collections.Generic.Dictionary<TKey,TValue>
					//     class with serialized data.
					//
					// Parameters:
					//   info:
					//     A System.Runtime.Serialization.SerializationInfo object containing the information
					//     required to serialize the System.Collections.Generic.Dictionary<TKey,TValue>.
					//
					//   context:
					//     A System.Runtime.Serialization.StreamingContext structure containing the
					//     source and destination of the serialized stream associated with the System.Collections.Generic.Dictionary<TKey,TValue>.
					//protected Dictionary(SerializationInfo info, StreamingContext context);

					// Summary:
					//     Gets the System.Collections.Generic.IEqualityComparer<T> that is used to
					//     determine equality of keys for the dictionary.
					//
					// Returns:
					//     The System.Collections.Generic.IEqualityComparer<T> generic interface implementation
					//     that is used to determine equality of keys for the current System.Collections.Generic.Dictionary<TKey,TValue>
					//     and to provide hash values for the keys.
					//public: IEqualityComparer<TKey> Comparer { get; }

					//
					// Summary:
					//     Gets the number of key/value pairs contained in the System.Collections.Generic.Dictionary<TKey,TValue>.
					//
					// Returns:
					//     The number of key/value pairs contained in the System.Collections.Generic.Dictionary<TKey,TValue>.
					public: override PROP3_GET(int, Count)
					{
						//my_struct<TKey>* s_users = static_cast<my_struct<TKey>*>(_internalMap);
						int size = HASH_COUNT(_internalMap);

						return size;
					}

					public: override PROP3_GET(bool, IsReadOnly)
					{
						throw;
					}

					public: override PROP3_GET(GC_PTR<ICollection<TKey>>, Keys)
					{
						return _Keys.get();
					}

					public: override PROP3_GET(GC_PTR<ICollection<TValue>>, Values)
					{
						return _Values.get();
					}
						
					/*
					public: override PROP3_GET(bool, IsReadOnly){ throw; }
					*/

					// Summary:
					//     Gets or sets the value associated with the specified key.
					//
					// Parameters:
					//   key:
					//     The key of the value to get or set.
					//
					// Returns:
					//     The value associated with the specified key. If the specified key is not
					//     found, a get operation throws a System.Collections.Generic.KeyNotFoundException,
					//     and a set operation creates a new element with the specified key.
					//
					// Exceptions:
					//   System.ArgumentNullException:
					//     key is null.
					//
					//   System.Collections.Generic.KeyNotFoundException:
					//     The property is retrieved and key does not exist in the collection.
					public: override TValue& operator[](TKey key)
					{
						//my_struct<TKey>* s_users = static_cast<my_struct<TKey>*>(_internalMap);

						int ikey = getKey(key);
						if(!ContainsKey(key))
						{
							throw KeyNotFoundException("The property is retrieved and key does not exist in the collection.");
						}
			
						my_struct<TKey>* s2(0);
#pragma warning( push )
#pragma warning( disable : 4127)
						HASH_FIND_INT( _internalMap, &ikey, s2 ); // s2: output pointer.
#pragma warning( pop )
			
						return s2->value;
					}

					// Summary:
					//     Adds the specified key and value to the dictionary.
					//
					// Parameters:
					//   key:
					//     The key of the element to add.
					//
					//   value:
					//     The value of the element to add. The value can be null for reference types.
					//
					// Exceptions:
					//   System.ArgumentNullException:
					//     key is null.
					//
					//   System.ArgumentException:
					//     An element with the same key already exists in the System.Collections.Generic.Dictionary<TKey,TValue>.
					public: override void Add(const TKey& key, const TValue& value)
					{
						//my_struct<TKey>* s_users = static_cast<my_struct<TKey>*>(_internalMap);

						int ikey = getKey(key);
						if(ContainsKey(key))
						{
							throw System::ArgumentException("An element with the same key already exists in the System.Collections.Generic.Dictionary<TKey,TValue>.");
						}
							
						// Add in map.
						my_struct<TKey> *s(0);
						s = new my_struct<TKey>();
						s->ikey = ikey;
						s->id = key;
						s->value = value;
						HASH_ADD_INT( _internalMap, ikey, s ); // id: name of key field.

						//_Keys.get()->Add(key);
						//_Values.get()->Add(value);
					}

					private: override void Add(const KeyValuePair<TKey, TValue>& item)
					{ 
						Add(item.Key, item.Value);
					}

					//
					// Summary:
					//     Removes all keys and values from the System.Collections.Generic.Dictionary<TKey,TValue>.
					public: void Clear()
					{
						//my_struct<TKey>* s_users = static_cast<my_struct<TKey>*>(_internalMap);
						HASH_CLEAR( hh, _internalMap );

						_listOfKeys.Clear();
					}

					//
					// Summary:
					//     Determines whether the System.Collections.Generic.Dictionary<TKey,TValue>
					//     contains the specified key.
					//
					// Parameters:
					//   key:
					//     The key to locate in the System.Collections.Generic.Dictionary<TKey,TValue>.
					//
					// Returns:
					//     true if the System.Collections.Generic.Dictionary<TKey,TValue> contains an
					//     element with the specified key; otherwise, false.
					//
					// Exceptions:
					//   System.ArgumentNullException:
					//     key is null.
					public: bool ContainsKey(const TKey& key)
					{
						//my_struct<TKey>* s_users = static_cast<my_struct<TKey>*>(_internalMap);

						int ikey = getKey(key);
						my_struct<TKey>* s(0);
			
#pragma warning( push )
#pragma warning( disable : 4127)
						HASH_FIND_INT( _internalMap, &ikey, s ); // s: output pointer.
#pragma warning( pop )
			
						// Return 1 if found a key, otherwise 0 if we not found enything.
						return (s == 0) ? false : true;
					}

					//
					// Summary:
					//     Determines whether the System.Collections.Generic.Dictionary<TKey,TValue>
					//     contains a specific value.
					//
					// Parameters:
					//   value:
					//     The value to locate in the System.Collections.Generic.Dictionary<TKey,TValue>.
					//     The value can be null for reference types.
					//
					// Returns:
					//     true if the System.Collections.Generic.Dictionary<TKey,TValue> contains an
					//     element with the specified value; otherwise, false.
					public: bool ContainsValue(const TValue& value)
					{
						//foreach(auto item : _Values)
						//{
						//	if(item == value)
						//	{
						//		return true;
						//	}
						//}
						//return false;
						throw;
					}

					private: bool Contains(const KeyValuePair<TKey, TValue>& item)
					{
						// Not needed.
						throw;
					}

					private: void CopyTo(Array<KeyValuePair<TKey, TValue>>* _array, int index)
					{
						//if(_array == nullptr)
						//{
						//	throw ArgumentNullException("Array to copy to may not be null.");
						//}
						//
						//if( index < 0 )
						//{
						//	throw ArgumentOutOfRangeException("Negative index");
						//}
						//
						//if((unsigned int)Count > sizeof(_array) / sizeof(KeyValuePair<TKey, TValue>) - index) 
						//{
						//	 throw ArgumentException("The number of elements in the source System.Collections.Generic.Dictionary<TKey,TValue>.\
						//							 KeyCollection is greater than the available space from index to the end of the destination array.");
						//}
						throw;
						/*
						for(std::map<TKey,TValue>::const_iterator item = _internalMap.begin(), int i = 0, int j = 0; 
						item != _internalMap.end(); ++item,  ++j){
						if(j < index) continue;
						KeyValuePair<TKey, TValue> kvPair;
						kvPair.Key = item->first;
						kvPair.Value = item->second;
						_array[i] = kvPair;
						++i
						}
						*/
					}
					private: bool Remove(const KeyValuePair<TKey, TValue>& item){ throw; }

					//
					// Summary:
					//     Returns an enumerator that iterates through the System.Collections.Generic.Dictionary<TKey,TValue>.
					//
					// Returns:
					//     A System.Collections.Generic.Dictionary<TKey,TValue>.Enumerator structure
					//     for the System.Collections.Generic.Dictionary<TKey,TValue>.
					public: Enumerator* GetEnumerator()
					{
						//_enum->setMax(_internalMap.end());
						//_enum->setIndex(_internalMap.begin());
						
						//my_struct<TKey>* s_users = static_cast<my_struct<TKey>*>(_internalMap);
						Enumerator* enumer = new Enumerator(_internalMap);
						return enumer;//_enum;
					}

					//
					// Summary:
					//     Implements the System.Runtime.Serialization.ISerializable interface and returns
					//     the data needed to serialize the System.Collections.Generic.Dictionary<TKey,TValue>
					//     instance.
					//
					// Parameters:
					//   info:
					//     A System.Runtime.Serialization.SerializationInfo object that contains the
					//     information required to serialize the System.Collections.Generic.Dictionary<TKey,TValue>
					//     instance.
					//
					//   context:
					//     A System.Runtime.Serialization.StreamingContext structure that contains the
					//     source and destination of the serialized stream associated with the System.Collections.Generic.Dictionary<TKey,TValue>
					//     instance.
					//
					// Exceptions:
					//   System.ArgumentNullException:
					//     info is null.
					//[SecurityCritical]
					//public: virtual void GetObjectData(SerializationInfo info, StreamingContext context);

					//
					// Summary:
					//     Implements the System.Runtime.Serialization.ISerializable interface and raises
					//     the deserialization event when the deserialization is complete.
					//
					// Parameters:
					//   sender:
					//     The source of the deserialization event.
					//
					// Exceptions:
					//   System.Runtime.Serialization.SerializationException:
					//     The System.Runtime.Serialization.SerializationInfo object associated with
					//     the current System.Collections.Generic.Dictionary<TKey,TValue> instance is
					//     invalid.
					//public: virtual void OnDeserialization(object sender);

					//
					// Summary:
					//     Removes the value with the specified key from the System.Collections.Generic.Dictionary<TKey,TValue>.
					//
					// Parameters:
					//   key:
					//     The key of the element to remove.
					//
					// Returns:
					//     true if the element is successfully found and removed; otherwise, false.
					//     This method returns false if key is not found in the System.Collections.Generic.Dictionary<TKey,TValue>.
					//
					// Exceptions:
					//   System.ArgumentNullException:
					//     key is null.
					public: bool Remove(const TKey& key)
					{
						//// TODO check if key exists.
						//if(!_Keys->Remove(key))
						//	return false;
						//
						//if(!_Values->Remove(_internalMap[key]))
						//	return false;
						//
						//_internalMap.erase(_internalMap.find(key));
						//return true;

						if(!ContainsKey(key))
						{
							return false;
						}

						//my_struct<TKey>* s_users = static_cast<my_struct<TKey>*>(_internalMap);
						
						int ikey = getKey(key);
						//void* ikey = reinterpret_cast<void*>(getKey(key));

						//for (int i = (int)_listOfKeys.Count - 1; i >= 0 ; i--)
						//{
						//	if(_listOfKeys[i] == ikey)
						//	{
						//		_listOfKeys.RemoveAt(i);
						//		break;
						//	}
						//}
			
						my_struct<TKey>* s(0);
#pragma warning( push )
#pragma warning( disable : 4127)
						HASH_FIND_INT( _internalMap, &ikey, s ); // s: output pointer.
#pragma warning( pop )
			
						HASH_DEL( _internalMap, s); // s: pointer to delete.
			
						free(s);

						return true;
					}

					//
					// Summary:
					//     Gets the value associated with the specified key.
					//
					// Parameters:
					//   key:
					//     The key of the value to get.
					//
					//   value:
					//     When this method returns, contains the value associated with the specified
					//     key, if the key is found; otherwise, the default value for the type of the
					//     value parameter. This parameter is passed uninitialized.
					//
					// Returns:
					//     true if the System.Collections.Generic.Dictionary<TKey,TValue> contains an
					//     element with the specified key; otherwise, false.
					//
					// Exceptions:
					//   System.ArgumentNullException:
					//     key is null.
					public: bool TryGetValue(const TKey& key, TValue out value)
					{
						throw;
					}
				};
			}
		};
	}
}

#endif // DICTIONARY_H